home *** CD-ROM | disk | FTP | other *** search
/ Black Crawling Systems Archive Release 1.0 / Black Crawling Systems Archive Release 1.0 (L0pht Heavy Industries, Inc.)(1997).ISO / blackcrwl / elctrnic / tomlpt.txt < prev    next >
Text File  |  1996-08-24  |  16KB  |  306 lines

  1.  
  2.  
  3.         Your PC's Printer Port: a Window on the Real World
  4.                     Tom Dickinson  tsd@bnl.gov
  5.  
  6.      The printer port or parallel port on your IBM computer is 
  7. well suited for hardware control, data input, or other 
  8. interfacing.  If you just send (write or output) a number to the 
  9. correct processor I/O port the corresponding bits will appear as 
  10. ones and zeros (5 volts and 0 volts) on the connector pins on the 
  11. printer adapter.  It's as simple as that.  It's nearly as simple 
  12. to get signals back, but there are only five bits of input -- the 
  13. status signals that the PC expects from the printer.  
  14.  
  15.      The printer port works well as a hardware interface because 
  16. it is a "real-time" device.  When you output a number to the 
  17. port, voltages appear on the connector pins, and when you input 
  18. you get the real time status of the bits (voltages) in the input 
  19. pins.  This is in contrast to the serial port which handles 
  20. things by the RS232 protocol and sends and receives strings of 
  21. pulses which have to be 're-assembled' into meaningful numbers.  
  22. RS232 also uses 'handshaking' signals to figure out when to start 
  23. and stop strings of pulses and when to expect another batch.  
  24. When the printer adapter is feeding a printer it also uses 
  25. handshaking, hardware interrupts and so forth, but for our simple 
  26. interfacing we can ignore these. 
  27.  
  28.      IBM compatible computers keep in touch with the outside 
  29. world mostly through processor I/O ports.  These are addressed 
  30. though the same address lines as memory, but use different 
  31. read/write lines, so they don't occupy memory address space.  The 
  32. Intel processors can address 64 k I/O ports, but the IBM machines 
  33. implement only about 1000 of these, which is plenty.  They are 
  34. used for keyboard, com and parallel ports, disk I/O, video, and 
  35. other things.  The processor I/O ports consist of logic built 
  36. into the processor and address assignments which permit the 
  37. processor to pass data back and forth in 8 bit chunks to 
  38. different destinations and sources.  They should be distinguished 
  39. from the connectors on the back of your computer for the serial 
  40. port, parallel port, etc.  Each of these uses several processor 
  41. I/O ports to carry out its functions.  More on this below.  
  42. Reading and writing to the I/O ports is slower than to memory, 
  43. and as computers have gotten faster and more sophisticated, some 
  44. of these functions have been changed to use Direct Memory Access 
  45. (DMA), in particular the newer video and disk interfaces.  
  46.  
  47.      IBM compatible computers accommodate three printer adapters, 
  48. that is, three sets of processor I/O ports are assigned to this 
  49. function.  When the computer boots up, the POST program detects 
  50. any printer adapters and assigns 'logical' ports to them, LPT1, 
  51. LPT2, and LPT3.  Which port addresses are assigned to LPT1, 2, or 
  52. 3 depends on whether the printer adapter is part of the video 
  53. card, but for hardware interfacing we don't care, since the 
  54. logical designations are mostly used by applications programs.  
  55.  
  56.      Each printer adapter uses three processor I/O ports.  The 
  57. first is for data output, the second for input of status signals 
  58. from the printer, and the third is for commands that go to the 
  59. printer.  The three are known as the data, status, and control 
  60. ports.  You can execute a 'read' to the first and third ports, 
  61. but all that you'll see is the state of the latches set by the 
  62. last 'write'.  Doing a read on the second port returns the state 
  63. of the five status signals on the printer connector, while 
  64. writing to that port doesn't do anything.  The physical address 
  65. of a printer adapter card is determined by how the computer 
  66. address lines are connected up to the logic on the card, and most 
  67. adapters have a jumper plug so you can select 378h or 278h.  The 
  68. first (data output) port is the base address, and the status and 
  69. control ports mentioned above are base+1 and base+2.  The three 
  70. base addresses available for printer adapters are 378h, 278h, and 
  71. 3BCh.  These are hexadecimal numbers, indicated by the 'h' after 
  72. each one.  
  73.  
  74.      You will need to know the physical addresses of your printer 
  75. adapter in order to send and get signals, so here's how to figure 
  76. it out.  If your printer connector is on your mono or CGA video 
  77. card, then the base address is almost certainly 3BCh.  That means 
  78. that the data output address is 3BCh, the status input address is 
  79. 3BDh and the control port is 3BEh.  (Base address, base+1, and 
  80. base+2.  Get the picture?)  If the printer connector is not on 
  81. the video adapter, then the address is probably 378h, and if not 
  82. that then it will be 278h.  If you can't figure it out, run the 
  83. program on the next page and check for the pattern of voltages on 
  84. the printer connector.  If it doesn't work, try again with a 
  85. different base address.  
  86.  
  87.      You can also use the same technique for finding the printer 
  88. adapter address that the computer does.  During the Power On Self 
  89. Test, the computer looks for adapter cards, keyboard etc, and 
  90. stores address and other configuration information in the BIOS 
  91. Data Area of memory.  The printer adapter base addresses are 
  92. stored at 40:0008h, and can be accessed by using DEBUG.  The 
  93. DEBUG program is probably on your DOS disk, so change to that 
  94. disk or directory and type debug and hit enter.  You will get a 
  95. minus sign (not blinking) at the left edge of the screen which is 
  96. the debug prompt.  Type the following (with no spaces): 
  97. - d40:0008      and hit return.  You will be rewarded with: 
  98.  
  99. 0040:0008                    78 03 78 02 00 00 00 00  x.x..... 
  100.  
  101. and several more lines of similar numbers and letters.
  102.      This is a "hex dump" of the contents of the eight memory 
  103. locations starting with 40:0008h.  The first six number pairs are 
  104. the base addresses of the installed printer adapters.  In the 
  105. example above, the first adapter is at 0378h, the second is at 
  106. 0278h, and there is no LPT3 installed.  The number pairs are 
  107. reversed because Intel stores such numbers in a 'low byte-high 
  108. byte' format.  If you only have one adapter installed, this tells 
  109. you all you need to know.  If you have more than one, you still 
  110. have to figure out which 25 pin printer connector is which, 
  111. either by opening up your computer and checking the address 
  112. selection jumpers on the adapter cards, or by doing the 
  113. experiment on the next page.  After you write down the addresses 
  114. displayed, you can exit DEBUG by typing q. 
  115.  
  116.      You can buy a printer adapter card for $10 to $20 and set it 
  117. to a different address than the one already in your computer so 
  118. you can play around with hardware I/O and still have your printer 
  119. plugged in and ready to go.  In fact, if your printer port is on 
  120. a multi I/O card or on your motherboard you should certainly do 
  121. this, so if you slip up and burn the port out, the damage is 
  122. limited.  
  123.  
  124.      Let's make something happen:  If you write a number to the 
  125. base address I/O port, pin 2 on the 25 pin printer connector on 
  126. the back of your pc corresponds to bit 0 and pin 9 corresponds to 
  127. bit 7 and the ones in between are in order.  So if you output 
  128. binary 10101010 (=hex AA =dec 170) on port 378h, and then take a 
  129. meter to the pins on the printer connector, you will find 5 volts 
  130. on pins 9, 7, 5, and 3, and zero on pins 8, 6,4, and 2.  When I 
  131. say 5 and 0 volts, I mean whatever is an LS-TTL high and low, 
  132. which may be between 2.4 and 5.0 volts for a high and 0.8 and 0.0 
  133. volts for a low.  Most printer adapters now days are made from 
  134. CMOS LSI chips, and the unloaded signals will be close to 5 and 0 
  135. volts.  These outputs are latched, so you don't need a software 
  136. loop or anything, they will stay there until a new number is 
  137. output to the printer port.  
  138.      In BASIC the relevant statement is OUT p,n  where p is port 
  139. and n is data, ie the number you want to output.  Try this 
  140. program. 
  141.  
  142. 10 INPUT "Enter a number 0 to 255   ", N%
  143. 20 OUT &H378, N%
  144.      (the &H tells BASIC that the number is hexadecimal, 
  145.       otherwise it expects decimal numbers)
  146. If you run this program, you should then find the pattern of 
  147. voltages on the printer connector corresponding to the bits of 
  148. the number you entered.  If your printer adapter is set to 378h, 
  149. that is.  If it doesn't work, try &H278 or &H3BC in line 20.
  150. The assembly language equivalent to the BASIC OUT statement is:
  151.  
  152. MOV DX,p
  153. MOV AL,n
  154. OUT DX,AL
  155.  
  156.      Inputing data to the PC is a little more complicated.  Bits 
  157. 3,4,5,6,and 7 correspond to connector pins 15, 13,12, 10, and 11 
  158. (note that they are not in order).  When you input a byte from 
  159. the status port at 379h, bits 3 through 7 will be set according 
  160. to what voltage is on the connector pins listed above.  I don't 
  161. know what is on bits 0, 1, and 2, but they are not determined by 
  162. connector voltages.  Another complication is that the input from 
  163. pin 11 is inverted, so a ground on the pin gives a one bit and 5 
  164. volts gives a zero bit.  The other inputs are the right way 
  165. round.  By the way, these are printer signals Error, Select, 
  166. Paper out, Acknowledge, and Busy. 
  167.      In BASIC to read a port you use the INP function.  To be 
  168. useful, you need to assign the number that you read to a 
  169. variable.  For example: 
  170.  
  171. 10 K% = INP(&H379)
  172. 20 N% = K% AND &HF8   rem F8h=binary 11111000. Strip last 3 bits
  173. 30 PRINT N%
  174.  
  175.      If you run this with nothing connected to the printer 
  176. connector, you should get 120 (= 78h = 01111000 bin).  This is 
  177. because an open TTL input usually reads high.  Remember that the 
  178. top bit is inverted, and the last three bits are not connected 
  179. and are zero'ed out in line 20 of the program.  Now ground pins 
  180. 15, 13, 12, 10, and 11 one at a time to see the effect on the 
  181. number returned.  Use a 2000 ohm resistor to do the grounding, 
  182. and you won't burn anything out if you stick it in the wrong 
  183. hole. 
  184.  
  185. The assembly equivalent of INP is:
  186.  
  187. MOV DX,p
  188. IN AL,DX
  189.  
  190. Where p is the input port (base+1).
  191.         
  192.      The control port at base+2 (37Ah to follow the examples 
  193. above), can be used for four more output bits if you need them.  
  194. Pins 1, 14, 16, and 17 correspond to bits 0 through 3 of a byte 
  195. output to the control port and bits 0, 1, and 3 of this are 
  196. inverted.  In addition, bit 4 of this control byte is not 
  197. connected to the printer connector, but if it is set, then the 
  198. next time pin 10 (the Acknowledge signal) goes from high to low, 
  199. the processor is interrupted.  This will invoke the interrupt 
  200. service routine for the Centronics protocol, and who knows what 
  201. will happen if you are trying to control a robot or something at 
  202. the time.  
  203.      You can also use this port for input.  This is complicated, 
  204. but may be worth it if you need a full 8 bit byte of input.  The 
  205. penalty comes in lines of programming needed to do it since you 
  206. first need to set the bottom three control outputs high, read 
  207. from the control and status ports, mask off the unused bits, 
  208. assemble the two sets of bits into a byte, then flip the inverted 
  209. bits.  The control port can be used for input because it has open 
  210. collector output circuits, and if you set the outputs high then 
  211. an external signal can determine the voltage on pins 1, 14, 16, 
  212. and 17 on the parallel connector.  Bits 0, 1, and 3 are inverted 
  213. on input as well as output. 
  214.  
  215.      To summarize:  on the 25 pin female 'D' connector on the 
  216. printer adapter, pins 2 through 9 correspond to bits 0 through 7 
  217. of a byte output to the adapter base address.  The voltages on 
  218. pins 15,13,12,10, and 11 determine bits 3 through 7 of the byte 
  219. input from base+1, and bit 7 will be inverted.  Pins 1, 14, 16, 
  220. and 17 are driven by bits 0 through 3 output to the control port 
  221. at base+2, and bits 0, 1, and 3 are inverted.  If the outputs on 
  222. these pins are set high by writing binary 00000100 to base+2 
  223. (remember the inverted bits) then external signals can be input 
  224. on these pins.  Pull-up resistors of 4.7k are built into the 
  225. printer adapter.  Pins 18 to 25 of the parallel connector are 
  226. ground.  Unfortunately, 5 volts does not appear on the connector, 
  227. so if you need power for interface circuits you will need an 
  228. external supply or to get it from somewhere inside the computer.  
  229. Be careful since you can cause expensive damage by putting 5 
  230. volts in the wrong place or shorting it to ground. 
  231.  
  232.      So what can we do with this?  The data bits can source a 
  233. couple of milliamps, so you could light (dimly) up to eight LED's 
  234. in patterns of your choice.  (This is one way to burn out your 
  235. printer adapter, so be sure you use the right size resistor to 
  236. limit the current to 2.6 mA if you are going to attach LED's). 
  237. Or, with an external power supply, you could drive transistors to 
  238. operate relays to control up to eight devices.  The inputs could 
  239. be used to keep track of whether five devices were on or off.  
  240. Not too exciting so far.  More possibilities are opened up with 
  241. an A to D converter, so you can measure things and perhaps make 
  242. decisions based on the measurements.  The ADC0831 is a nifty 
  243. eight bit A-D converter which can be operated with two output and 
  244. one input lines, leaving lots of I/O lines still available for 
  245. doing stuff.  Description of this is left for another time. 
  246.  
  247.  
  248.     How to Input 8 bits Through a Unidirectional Parallel Port
  249.                    Tom Dickinson  tsd@bnl.gov
  250.  
  251.      The scheme I suggest for 8 bit input uses the three lowest 
  252. bits of the control port and the five high bits from the status 
  253. port.  This is also described in Zhahai Stewart's "Parallel Port 
  254. FAQ" in section 16, mode 3B.  We evidently thought of this 
  255. independently, but it is pretty obvious.  This leaves one control 
  256. bit (bit 3) unused, and it could be used as a bidirectional 
  257. control or strobe bit as mentioned in the faq.  
  258.      Here are some code examples:
  259. 8 bit output through the data port:
  260.  
  261.      OUT &H378, N  'where N is the number you want to output
  262.  
  263. In assembly this is:
  264.      MOV DX,p
  265.      MOV AL,n
  266.      OUT DX,AL     ' p is port and n is data
  267.  
  268. Here is an example of an 8 bit input using 3 control bits and 5 
  269. status bits.  This is in basic to show the operations involved.
  270.   (I haven't tried this code, so it may have bugs)
  271.  
  272. The bits to be input are connected to the following pins:
  273.      BIT  7  6  5  4  3  2  1  0
  274.      PIN  11 10 12 13 15 16 14 1
  275.  
  276.      OUT &H37A, &H04 'set output of bits 0-3 of cont. port high
  277.      LO = INP(&H37A) AND &H07     'input and mask bottom 3 bits
  278.      HI = INP(&H379) AND &HF8     'input and mask top 5 bits
  279.      BYTE = LO OR HI              'combine LO and HI into 8 bits
  280.      RITEBYTE = BYTE XOR &H83     'flip bits 0, 1, and 7
  281. Ritebyte is the number (0 to 255) represented by the 8 bits input 
  282. on the connector.  
  283.  
  284.      The first line above may be a bit confusing, but remember 
  285. that bits 0, 1, and 3 are inverted, so to get 1111 on the pins, 
  286. you need to send out 0100.  04h = 00000100, so we also are 
  287. zeroing the top 4 bits.  This insures that the interrupt enable 
  288. on bit four is not set, which might cause trouble.  In basic this 
  289. routine is apt to be pretty slow, and if you need speed, you 
  290. should code in assembly.  These are byte wide logical operations 
  291. which are very fast in machine language.  You would then pass the 
  292. byte to a high level language to use as an integer variable.  I 
  293. understand that C can do this kind of stuff very fast, if 
  294. optimized.  I have no experience with this.
  295.  
  296. ------------------------------------------------------------------
  297. Thomas S. Dickinson                     Internet: tsd@bnl.gov 
  298. National Synchrotron Light Source       (516) 282-7196  (work)
  299. Brookhaven National Laboratory          (516) 282-3238  (fax)
  300. Upton, NY 11973 USA                     
  301.                            also  dickinso@ls7501.nsls.bnl.gov
  302.                            and   dickinso@bnlls1.nsls.bnl.gov
  303. -----------------------------------------------------------------
  304.  
  305.  
  306.